<?php


namespace App\Core\Facades;


use App\Core\Ioc;
use RuntimeException;

abstract class Facade
{
    /**
     * @var Ioc $app
     */
    public static $app;

    public static $resolvedInstance;


    /**
     * @param Ioc $app
     */
    public static function setFacadeApplication(Ioc $app): void
    {
        self::$app = $app;
    }

    public static function getFacadeRoot()
    {
        return static::resolveFacadeInstance(static::getFacadeAccessor());
    }

    protected static function resolveFacadeInstance($name)
    {
        if (is_object($name)) {
            return $name;
        }
        if (!isset(static::$resolvedInstance[$name])) {
            static::$resolvedInstance[$name] = static::$app->make($name);
        }
        return static::$resolvedInstance[$name];
    }

    protected static function getFacadeAccessor()
    {
        throw new RuntimeException("Facade does not implement getFacadeAccessor method.");
    }


    public static function __callStatic($method, $arguments)
    {
        $instance = static::getFacadeRoot();
        if (!$instance) {
            throw new RuntimeException("A facade root has not been set.");
        }
        return $instance->$method(...$arguments);
    }
}